package com.zhuoyue.biz.core.command.cmd.common.fac;

import com.zhuoyue.biz.core.api.domain.DeviceAndGatewayDO;
import com.zhuoyue.biz.core.api.dto.req.ControlReq;
import com.zhuoyue.biz.core.command.cmd.common.fe6.HongWaiXueXiYi0Fe60202;
import com.zhuoyue.biz.core.command.model.BaseParams;
import com.zhuoyue.common.constant.ControlType;
import com.zhuoyue.common.exception.ErrorType;
import com.zhuoyue.common.exception.ZyServerException;
import com.zhuoyue.common.utils.CmdUtils;
import lombok.Data;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;

import javax.validation.constraints.NotBlank;
import java.util.Map;

/**
 * @author wjming
 */
public class SmartAirPartner0Fac0503 {
    /**
     * 子索引16(模式):
     * 01=打开，02=关闭
     * <p>
     * 子索引17(模式):
     * 03=制冷，04=制热，05=除湿，06=送风
     * <p>
     * 子索引18(风速):
     * 02=低风，03=中风，04=高风，05=自动。
     * <p>
     * 子索引19(温度):
     * BCD码，单位0.01摄氏度
     */
    private static final String AIR_STATUS = "0201${gatewayMac}${deviceMac}0FAC${childOd}01${status}";

    private static final String AIR_SET_TEMPLATE = "0201${gatewayMac}${deviceMac}0FAC${childOd}02${status}";


    /**
     * 设置所有参数
     */
    private static final String AIR_SET_ALL = "0201${gatewayMac}${deviceMac}0FACFF0900F0000001${mode}${wind}${temperature}";

    /**
     * 定时任务task:02,03,04
     */
    private static final String AIR_TASK_TIME = "0201${gatewayMac}${deviceMac}1778${task}0D${isEnable}${repeatTime}${taskInterval}${time}{controlType}${controlParam}";

    /**
     * 设置型号
     */
    private static final String AIR_SET_TYPE = "0201${gatewayMac}${deviceMac}03EF0F02${modelNumber}";

    /**
     * 读取定时任务
     */
    private static final String AIR_READ_TIME_TASK = "0101${gatewayMac}${deviceMac}1778{task}";

    public static String control(DeviceAndGatewayDO deviceAndGatewayDo, ControlReq controlReq) {
        String cmd = "";
        String gatewayMac = deviceAndGatewayDo.getGatewayMac();
        String deviceMac = deviceAndGatewayDo.getZigbeeMac();
        Map<String, Object> actions = controlReq.getActions();
        //最低温度
        final int template1 = 16;
        //最高温度
        final int template2 = 32;
        switch (controlReq.getControlType()) {
            case ControlType.TURN_ON_REQUEST:
                cmd = new SmartAirPartnerAttribute(gatewayMac, deviceMac, "16", "01").getCmd(AIR_STATUS);
                break;
            case ControlType.TURN_OFF_REQUEST:
                cmd = new SmartAirPartnerAttribute(gatewayMac, deviceMac, "16", "02").getCmd(AIR_STATUS);
                break;
            case ControlType.SET_MODE_REQUEST:
                String modeState = AcEnum.getAcEnum((String) actions.get("modeState"));
                cmd = new SmartAirPartnerAttribute(gatewayMac, deviceMac, "17", modeState).getCmd(AIR_STATUS);
                break;
            case ControlType.SET_FAN_SPEED_REQUEST:
                String windRankState = AcEnum.getAcEnum((String) actions.get("windRankState"));
                cmd = new SmartAirPartnerAttribute(gatewayMac, deviceMac, "18", windRankState).getCmd(AIR_STATUS);
                break;
            case ControlType.SET_TEMPERATURE_REQUEST:
                int temperature = Integer.parseInt((String) actions.get("temperature"));
                if (temperature > template2 || temperature < template1) {
                    throw new ZyServerException(ErrorType.INVALID_PARAMS.getCode(), "温度设置失败不能低于16或高于32");
                }
                cmd = new SmartAirPartnerAttribute(gatewayMac, deviceMac, "19", temperature + "00").getCmd(AIR_SET_TEMPLATE);
                break;
            case ControlType.AC_SET_MODEL_NUMBER:
                cmd = new SmartAirSetModelNumber(gatewayMac, deviceMac, (String) actions.get("modelNumber")).getCmd(AIR_SET_TYPE);
                break;
            case ControlType.SET_ALL:
                String modeState1 = AcEnum.getAcEnum((String) actions.get("modeState"));
                String windRankState1 = AcEnum.getAcEnum((String) actions.get("windRankState"));
                int temperature1 = Integer.parseInt((String) actions.get("temperature"));
                if (temperature1 > template2 || temperature1 < template1) {
                    throw new ZyServerException(ErrorType.INVALID_PARAMS.getCode(), "温度设置失败不能低于16或高于32");
                }
                cmd = new SmartAirPartnerSetAllAttribute(gatewayMac, deviceMac, modeState1, windRankState1, temperature1 + "00").getCmd(AIR_SET_ALL);
                break;
            case ControlType.SET_TIMED_TASK:
            case ControlType.SET_TIMED_TASK_STATUS:
                //删除定时任务
            case ControlType.DELETE_TIMED_TASK:
                cmd = HongWaiXueXiYi0Fe60202.control(deviceAndGatewayDo, controlReq);
                break;
            default:
                throw new ZyServerException(ErrorType.INVALID_PARAMS.getCode(), "参数错误");
        }
        return cmd;
    }

}

/**
 * 设置空调基本参数
 */
@Data
class SmartAirPartnerAttribute extends BaseParams {
    /**
     * 子索引
     */
    private String childOd;
    /**
     * 状态
     * 01=打开，02=关闭,03=制冷，04=制热，05=除湿，06=送风
     */
    private String status;

    public SmartAirPartnerAttribute(String gatewayMac, String deviceMac, String childOd, String status) {
        super(gatewayMac, deviceMac);
        this.childOd = childOd;
        this.status = status;
    }
}

@Data
class SmartAirSetModelNumber extends BaseParams {
    private String modelNumber;

    public SmartAirSetModelNumber(String gatewayMac, String deviceMac, @NotBlank(message = "设置的型号不能为空") String modelNumber) {
        super(gatewayMac, deviceMac);
        this.modelNumber = modelNumber;
    }
}

/**
 * 设置所有控制参数
 */
@Data
class SmartAirPartnerSetAllAttribute extends BaseParams {
    /**
     * 空调模式
     * 03=制冷，04=制热，05=除湿，06=送风
     */
    private String mode;
    /**
     * 风速
     */
    private String wind;
    /**
     * 温度
     */
    private String temperature;

    public SmartAirPartnerSetAllAttribute(String gatewayMac, String deviceMac, String mode, String wind, String temperature) {
        super(gatewayMac, deviceMac);
        this.mode = mode;
        this.wind = wind;
        this.temperature = temperature;
    }
}

/**
 * 设置时间
 */
@Data
class SetOrReadAirTimeTask extends BaseParams {
    /**
     * 定时任务
     */
    private String task;
    /**
     * 定时是否启用
     */
    private String isEnable;
    /**
     * 重复次数
     */
    private String repeatTime;
    /**
     * 重发间隔
     */
    private String taskInterval;
    /**
     * 定时时间
     */
    private String time;
    /**
     * 控制类型
     */
    private String controlType;
    /**
     * 控制参数
     */
    private String controlParam;

    /**
     * 设置定时任务
     *
     * @param gatewayMac
     * @param deviceMac
     * @param task
     * @param isEnable
     * @param repeatTime
     * @param taskInterval
     * @param time
     * @param controlType
     * @param controlParam
     */
    public SetOrReadAirTimeTask(String gatewayMac, String deviceMac, String task, String isEnable, String repeatTime, String taskInterval, String time, String controlType, String controlParam) {
        super(gatewayMac, deviceMac);
        this.task = task;
        this.isEnable = isEnable;
        this.repeatTime = repeatTime;
        this.taskInterval = taskInterval;
        this.time = time;
        this.controlType = controlType;
        this.controlParam = controlParam;
    }

    /**
     * 读取定时任务
     *
     * @param gatewayMac
     * @param deviceMac
     * @param task
     */
    public SetOrReadAirTimeTask(String gatewayMac, String deviceMac, String task) {
        super(gatewayMac, deviceMac);
        this.task = task;
    }
}

@Getter
enum AcEnum {
    /**
     * 开
     */
    OPEN("OPEN", "01"),
    /**
     * 关
     */
    CLOSE("CLOSE", "02"),
    /**
     * 自动风向
     */
    WIND_DIRECTION_AUTO("WIND_DIRECTION_AUTO", "01"),
    /**
     * 手动风向
     */
    WIND_DIRECTION_MANUAL("WIND_DIRECTION_MANUAL", "02"),

    /**
     * 低风
     */
    LOW_WIND("LOW", "02"),

    /**
     * 中风
     */
    MID_WIND("MID", "03"),

    /**
     * 高风
     */
    HIGH_WIND("HIGH", "04"),

    /**
     * 自动
     */
    AUTO_WIND("AUTO", "05"),

    /**
     * 制冷模式
     */
    COLD_MODEL("COLD", "03"),

    /**
     * 制热模式
     */
    HEAT_MODEL("HEAT", "04"),

    /**
     * 除湿模式
     */
    DEHUMIDIFICATION_MODEL("DEHUMIDIFICATION", "05"),

    /**
     * 送风模式
     */
    WIND_MODEL("WIND", "06"),

    //任务1-3
    TASK_1("1", "02"),

    TASK_2("2", "03"),

    TASK_3("3", "04"),

    //是否启用
    ENABLE("enable", "01"),

    UN_ENABLE("unEnable", "00");

    private String key;
    private String value;

    AcEnum(String key, String value) {
        this.key = key;
        this.value = value;
    }

    /**
     * 根据Key得到枚举的Value
     * 普通for循环遍历，比较判断
     *
     * @param key
     * @return
     */
    public static String getAcEnum(String key) {
        AcEnum[] acWindEnums = AcEnum.values();
        for (int i = 0; i < acWindEnums.length; i++) {
            if (key.equals(acWindEnums[i].getKey())) {
                return acWindEnums[i].getValue();
            }
        }
        return "";
    }
}

@Getter
enum AcTimeTaskEnum {
    /**
     * 开
     */
    OPEN("OPEN", "01"),
    /**
     * 关
     */
    CLOSE("CLOSE", "02"),
    /**
     * 自动风向
     */
    WIND_DIRECTION_AUTO("WIND_DIRECTION_AUTO", "01"),
    /**
     * 手动风向
     */
    WIND_DIRECTION_MANUAL("WIND_DIRECTION_MANUAL", "02"),

    /**
     * 低风
     */
    LOW_WIND("LOW", "01"),

    /**
     * 中风
     */
    MID_WIND("MID", "02"),

    /**
     * 高风
     */
    HIGH_WIND("HIGH", "03"),

    /**
     * 自动
     */
    AUTO_WIND("AUTO", "04"),

    /**
     * 制冷模式
     */
    COLD_MODEL("COLD", "01"),

    /**
     * 制热模式
     */
    HEAT_MODEL("HEAT", "02"),

    /**
     * 除湿模式
     */
    DEHUMIDIFICATION_MODEL("DEHUMIDIFICATION", "03"),

    /**
     * 送风模式
     */
    WIND_MODEL("WIND", "04"),
    AUTO_MODEL("AUTO_MODEL", "05");


    private String key;
    private String value;

    AcTimeTaskEnum(String key, String value) {
        this.key = key;
        this.value = value;
    }

    /**
     * 根据Key得到枚举的Value
     * 普通for循环遍历，比较判断
     *
     * @param key
     * @return
     */
    public static String getTimeTaskEnum(String key) {
        AcEnum[] acWindEnums = AcEnum.values();
        for (int i = 0; i < acWindEnums.length; i++) {
            if (key.equals(acWindEnums[i].getKey())) {
                return acWindEnums[i].getValue();
            }
        }
        return "";
    }
}

@Getter
enum AcTimeTaskNotAllEnum {
    /**
     * 开
     */
    OPEN("OPEN", "01FFFFFFFFFF"),
    /**
     * 关
     */
    CLOSE("CLOSE", "02FFFFFFFFFF"),
    /**
     * 自动风向
     */
    WIND_DIRECTION_AUTO("AUTO", "FFFFFF01FFFF"),
    /**
     * 手动风向
     */
    WIND_DIRECTION_MANUAL("MANUAL", "FFFFFF02FFFF"),

    /**
     * 低风
     */
    LOW_WIND("LOW", "FFFF01FFFFFF"),

    /**
     * 中风
     */
    MID_WIND("MID", "FFFF02FFFFFF"),

    /**
     * 高风
     */
    HIGH_WIND("HIGH", "FFFF03FFFFFF"),

    /**
     * 自动
     */
    AUTO_WIND("AUTO", "FFFF04FFFFFF"),

    /**
     * 制冷模式
     */
    COLD_MODEL("COLD", "FF01FFFFFFFF"),

    /**
     * 制热模式
     */
    HEAT_MODEL("HEAT", "FF02FFFFFFFF"),

    /**
     * 除湿模式
     */
    DEHUMIDIFICATION_MODEL("DEHUMIDIFICATION", "FF03FFFFFFFF"),

    /**
     * 送风模式
     */
    WIND_MODEL("WIND", "FF04FFFFFFFF"),
    /**
     * 自动模式
     */
    AUTO_MODEL("AUTO_MODEL", "FF05FFFFFFFF");


    private String key;
    private String value;

    AcTimeTaskNotAllEnum(String key, String value) {
        this.key = key;
        this.value = value;
    }

    /**
     * 根据Key得到枚举的Value
     * 普通for循环遍历，比较判断
     *
     * @param key
     * @return
     */
    public static String getTimeTaskNotAllEnum(String key) {
        AcEnum[] acWindEnums = AcEnum.values();
        for (int i = 0; i < acWindEnums.length; i++) {
            if (key.equals(acWindEnums[i].getKey())) {
                return acWindEnums[i].getValue();
            }
        }
        return "";
    }
}

@Getter
enum AcControlTypeEnum {
    /**
     * 空调开关
     */
    STATUS("status", "01"),
    /**
     * 空调模式
     */
    MODE("mode", "02"),
    /**
     * 空调风速
     */
    WIND_SPEED("windSpeed", "03"),
    /**
     * 空调风向
     */
    WIND_DIRECTION("windDirection", "04"),
    /**
     * 空调温度
     */
    TEMPLATE("template", "05"),
    /**
     * 全控
     */
    ALL("all", "06");


    private String key;
    private String value;

    AcControlTypeEnum(String key, String value) {
        this.key = key;
        this.value = value;
    }

    /**
     * 根据Key得到枚举的Value
     * 普通for循环遍历，比较判断
     *
     * @param key
     * @return
     */
    public static String getTypeEnum(String key) {
        AcEnum[] acWindEnums = AcEnum.values();
        for (int i = 0; i < acWindEnums.length; i++) {
            if (key.equals(acWindEnums[i].getKey())) {
                return acWindEnums[i].getValue();
            }
        }
        return "";
    }
}

/**
 * @author wjming
 * @ClassName: TaskTimeBase
 * @Description: 定时任务基础信息
 * @Date 2021-11-02 10:22
 */
@Data
class TaskTimeActionBase {
    private String task;
    private String isEnable;
    private int repeatTime;
    private int taskInterval;
    /**
     * 时
     */
    private int hour;
    /**
     * 分
     */
    private int minute;

    private String type;
}

/**
 * @author wjming
 * @ClassName: AllParamsTask
 * @Description: 定时任务Action所有参数数据
 * @Date 2021-11-02 10:22
 */
@Data
class AllParamsTask {
    /**
     * 温度
     */
    private String temperature;
    /**
     * 开关状态
     */
    private String status;
    /**
     * 空调模式
     */
    private String mode;
    /**
     * 风速
     */
    private String windSpeed;
    /**
     * 风向
     */
    private String windDirection;

    /**
     * 获取全控数据帧
     *
     * @return
     */
    public String getAllParamsCmd() {
        String tempeValue = "0" + StringUtils.replace(this.temperature, ".", "");
        String temperatureValue = CmdUtils.getHighPositionReplacement(tempeValue);
        String status = AcTimeTaskEnum.getTimeTaskEnum(this.status);
        String mode = AcTimeTaskEnum.getTimeTaskEnum(this.mode);
        String windSpeed = AcTimeTaskEnum.getTimeTaskEnum(this.windSpeed);
        String windDirection = AcTimeTaskEnum.getTimeTaskEnum(this.windDirection);
        return status + mode + windSpeed + windDirection + temperatureValue;
    }
}


